﻿package ygg.encoding.swf
{
	import flash.utils.ByteArray;
	import j.sus2maj7.encoding.*;
	
	import ygg.encoding.swf.structure.*;
	
	public class SwfBinary extends AbstractBinary
	{
		
		private var _bitPos:int;
		private var _bitBuf:int;
		
		public function SwfBinary(ba:ByteArray=null)
		{
			super(ba);
		}
		
		public function readString():String
		{
			var s:String = ""
			var c:int

			while (c = ba.readUnsignedByte())
			{
				s += String.fromCharCode(c);
			}

			return s
		}
		
		public function syncBits():void
		{
			_bitPos = 0;
		}
		
	    public function decodeRect():Rect
	    {
	        syncBits();
	
	        var rect:Rect = new Rect();
	
	        var nBits:int = readUBits(5)
	        rect.xMin = readSBits(nBits);
	        rect.xMax = readSBits(nBits);
	        rect.yMin = readSBits(nBits);
	        rect.yMax = readSBits(nBits);
	
	        return rect;
	    }
	
	    public function readSBits(numBits:int):int
	    {
	        if (numBits > 32)
	            throw new Error("Number of bits > 32");

	        var num:int = readUBits(numBits);
	        var shift:int = 32-numBits;
	        // sign extension
	        num = (num << shift) >> shift;
	        return num;
	    }
	
		public function readUBits(numBits:int):uint
	    {
	        if (numBits == 0)
			{
				return 0;
			}
	
	        var bitsLeft:int = numBits;
	        var result:int = 0;
	
	        if (_bitPos == 0) //no value in the buffer - read a byte
	        {
	            _bitBuf = ba.readUnsignedByte()
	            _bitPos = 8;
	        }

	        //while (true)
	        while (1==1)
	        {
				
	            var shift:int = bitsLeft - _bitPos;
	            if (shift > 0)
	            {
	                // Consume the entire buffer
	                result |= _bitBuf << shift;
	                bitsLeft -= _bitPos;
					
	                // Get the next byte from the input stream
	                _bitBuf = ba.readUnsignedByte();
	                _bitPos = 8;
	            }
	            else
	            {
	                // Consume a portion of the buffer
	                result |= _bitBuf >> -shift;
	                _bitPos -= bitsLeft;
	                _bitBuf &= 0xff >> (8 - _bitPos); // mask off the consumed bits
					
					return result;
	            }
	        }
			
			return result; //added
	    }
		
		protected function get bitPos():int { return _bitPos; }
		
		protected function set bitPos(value:int):void
		{
			_bitPos = value;
		}
		
		protected function get bitBuf():int { return _bitBuf; }
		
		protected function set bitBuf(value:int):void
		{
			_bitBuf = value;
		}
	}
}